{*******************************************************************************
* The contents of this file are used with permission, subject to the Mozilla   *
* Public License Version 1.1 (the "License"); you may not use this file except *
* in compliance with the License. You may obtain a copy of the License at      *
* http://www.mozilla.org/MPL/                                                  *
*                                                                              *
* Software distributed under the License is distributed on an "AS IS" basis,   *
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for *
* the specific language governing rights and limitations under the License.    *
*                                                                              *
* The Original Code is distributed as part of the "mediate" product and is     *
* Copyright (C) @home media limited. All Rights Reserved.                      *
*                                                                              *
* Email: support@athomemedia.co.uk                                             *
* Web:   http://www.athomemedia.co.uk                                          *
*******************************************************************************}

unit MediaGrids;

interface

uses Classes, UIObjects, UIControls, UIGrids, AHMTypes, XMLHelper;

{$IFDEF DESIGNER}
const
  // Property categories and hints for designer
  CAT_MEDIA = 'Media';
  HINT_TITLEITEM = 'specifies the name of a grid item to use for drawing media title';
  HINT_AUTHORITEM = 'specifies the name of a grid item to use for drawing media author';
  HINT_TIMEITEM = 'specifies the name of a grid item to use for drawing media duration';
  HINT_MEDIATYPE = 'determines the type of media content shown in the grid';
  HINT_STREAMTYPE = 'controls which playlist will be shown for Playlist media type';
{$ENDIF}

type
  // Enumerated type to expose susbet of supported media types in theme designer
  TAHMMediaGridType = (mgAudio, mgVideo, mgPictures, mgRadio, mgAll);

  TAHMMediaGrid = class(TAHMGrid)
  private
    FMediaType: TAHMMediaType;
    FStreamType: TAHMStreamType;
  protected
    function GetMediaGridType: TAHMMediaGridType;
    procedure SetMediaGridType(MediaType: TAHMMediaGridType);
    procedure SetStreamType(StreamType: TAHMStreamType);
    procedure ClearProperties; override;
  public
    constructor Create(const Name: String); override;
    property MediaType: TAHMMediaType read FMediaType write FMediaType;
    procedure Assign(Source: TPersistent); override;
    procedure SaveXMLBody(Lines: TStrings); override;
    procedure ParseFromXML(XML: TAHMXMLHelper); override;
    procedure BuildProperties(Properties: TAHMUIPropertyList); override;
  published
    property GridType: TAHMMediaGridType read GetMediaGridType write SetMediaGridType;
    property StreamType: TAHMStreamType read FStreamType write SetStreamType;
  end;

  TAHMMediaGridList = class(TAHMUIObjectList)
  private
  protected
  public
    constructor Create; override;
    function AddMediaGrid(const InheritFrom, NewName: String): TAHMMediaGrid;
    function GetMediaGrid(const Name: String): TAHMMediaGrid;
    procedure PopulateDefaultObjects; override;
  end;

function GetMediaItemImageIndex(MediaType: TAHMMediaType): String;

implementation

uses SysUtils, ApplicationManager, BaseControls, GridItems, Bitmaps, TagNames,
     XMLTags, ErrorCodes;


function GetMediaItemImageIndex(MediaType: TAHMMediaType): String;
begin
  // Convert passed media type to a default image name
  case MediaType of
    mtParent: Result := MEDIA_VAL_PARENT;
    mtFolder: Result := MEDIA_VAL_FOLDER;
    mtPlaylist: Result := MEDIA_VAL_PLAYLIST;
    mtTheme: Result := MEDIA_VAL_THEME;
    mtImage: Result := MEDIA_VAL_PICTURE;
    mtAudio: Result := MEDIA_VAL_AUDIO;
    mtRadio: Result := MEDIA_VAL_RADIO;
    mtVideo: Result := MEDIA_VAL_VIDEO;
    mtDVD: Result := MEDIA_VAL_DVD;
    mtInfo: Result := MEDIA_VAL_INFO;
    else Result := MEDIA_VAL_UNKNOWN;
  end;
end;

//----------------------------------------------------------------------------//

constructor TAHMMediaGridList.Create;
begin
  inherited Create;

  XMLTagName := TAG_MEDIAGRIDS;
  ChildClass := TAHMMediaGrid;
end;

function TAHMMediaGridList.AddMediaGrid(const InheritFrom, NewName: String): TAHMMediaGrid;
begin
  Result := TAHMMediaGrid(Inherit(InheritFrom, NewName));
end;

function TAHMMediaGridList.GetMediaGrid(const Name: String): TAHMMediaGrid;
begin
  Result := TAHMMediaGrid(GetObject(Name));
end;

procedure TAHMMediaGridList.PopulateDefaultObjects;
begin
  with ApplicationManagerInstance.ThemeManager, DefaultObject as TAHMMediaGrid do
  begin
    VirtualWidth := DEFAULT_CTRL_WIDTH * 2;
    VirtualHeight := DEFAULT_CTRL_WIDTH;
    VirtualImageWidth := DEFAULT_CTRL_HEIGHT div 2;
    VirtualImageHeight := DEFAULT_CTRL_HEIGHT div 2;
    RowCount := 5;
    ColumnCount := 1;
    TextItem := TAHMGridItem(ThemeObjects[otGridItems].DefaultObject);
  end;
end;

//----------------------------------------------------------------------------//

constructor TAHMMediaGrid.Create(const Name: String);
begin
  inherited Create(Name);

  XMLTagName := TAG_MEDIAGRID;
  ObjectType := otMediaGrids;
  ImageIndex := Ord(otMediaGrids);
  
  ClearProperties;
  DefaultImages.StateType := stMedia;

{$IFDEF DESIGNER}
  // Render preview using a media grid control
  PreviewControlClass := TAHMMediaGridControl;
{$ENDIF}
end;

function TAHMMediaGrid.GetMediaGridType: TAHMMediaGridType;
begin
  // Map media type to supported media grid type
  case FMediaType of
    mtAudio: Result := mgAudio;
    mtVideo: Result := mgVideo;
    mtImage: Result := mgPictures;
    mtRadio: Result := mgRadio;
    else Result := mgAll;
  end;
end;

procedure TAHMMediaGrid.SetMediaGridType(MediaType: TAHMMediaGridType);
var
  NewMediaType: TAHMMediaType;
begin
  // Map supported media grid type to media type
  case MediaType of
    mgAudio:    NewMediaType := mtAudio;
    mgVideo:    NewMediaType := mtVideo;
    mgPictures: NewMediaType := mtImage;
    mgRadio:    NewMediaType := mtRadio;
    else NewMediaType := mtAll;
  end;

  if FMediaType <> NewMediaType then
  begin
    FMediaType := NewMediaType;
    ApplicationManagerInstance.UIManager.InvalidateUIObject(Self);
  end;
end;

procedure TAHMMediaGrid.SetStreamType(StreamType: TAHMStreamType);
begin
  if FStreamType <> StreamType then
  begin
    FStreamType := StreamType;
    ApplicationManagerInstance.UIManager.InvalidateUIObject(Self);
  end;
end;

procedure TAHMMediaGrid.ClearProperties;
begin
  inherited;

  // Clear custom media grid properties
  FMediaType := mtAll;
  FStreamType := stPrimary;
end;

procedure TAHMMediaGrid.Assign(Source: TPersistent);
begin
  inherited Assign(Source);

  with Source as TAHMMediaGrid do
  begin
    Self.MediaType := MediaType;
    Self.StreamType := StreamType;
  end;
end;

procedure TAHMMediaGrid.SaveXMLBody(Lines: TStrings);
var
  oAncs: TAHMMediaGrid;
begin
  // Populate standard grid stuff from ancestor
  inherited SaveXMLBody(Lines);

  // Determine which ancestor to compare against - real or empty
  oAncs := TAHMMediaGrid(ObjectToCompare);

  // Do we need to store media/stream type?
  if ((FMediaType <> mtUnknown) and (FMediaType <> oAncs.MediaType)) or
     (FStreamType <> oAncs.StreamType) then
    Lines.Add(TABS[3] + TGB+TAG_MEDIATYPE+SPC+ATTR_MODE+ATB + MediaType2Str(FMediaType) +
                        ATN+ATTR_STREAM+ATB + StreamType2Str(FStreamType) + ATE);
end;

procedure TAHMMediaGrid.ParseFromXML(XML: TAHMXMLHelper);
var
  sMode, sStream: String;
  GridNode, PropsNode: TAHMXMLNode;
begin
  // Initialise parsing nodes
  GridNode := XML.CurrentNode;
  PropsNode := nil;

  // All media grid elements are optional, so see what we have
  while XML.NextElement(GridNode, PropsNode) do
    if XML.CurrentElement = TAG_MEDIATYPE then
    begin
      // Get media type
      sMode := XML.GetAttribute(ATTR_MODE);
      sStream := XML.GetAttribute(ATTR_STREAM);
      MediaType := Str2MediaType(sMode);
      StreamType := Str2StreamType(sStream);
    end
    else
    begin
      // Handle common XML tags from base grid class
      ParseCommonXML(XML);
    end;
end;

procedure TAHMMediaGrid.BuildProperties(Properties: TAHMUIPropertyList);
begin
{$IFDEF DESIGNER}
  inherited;

  // Build custom media grid properties
  Properties.Add('Media Type', 'GridType', CAT_MEDIA, HINT_MEDIATYPE);
//TODO: media grid stream type property should also be used to implement default selection
//      behaviour for media events, i.e. clearpl, replacepl etc. for the appropriate media
//      stream. Once this is working properly and the playlist media type is also showing
//      correct contents with shuffle, repeat all working properly we can then enable the
//      stream type property in the designer. For the time being leave it disabled
//
//  Properties.Add('Playlist', 'StreamType', CAT_MEDIA, HINT_STREAMTYPE);

  // Rename text, description and data to media specific terms
  Properties.Remove('TextItem');
  Properties.Remove('DescriptionItem');
  Properties.Remove('DataItem');
  Properties.Add('Title Item', 'TextItem', CAT_ITEMS, HINT_TITLEITEM);
  Properties.Add('Author Item', 'DescriptionItem', CAT_ITEMS, HINT_AUTHORITEM);
  Properties.Add('Duration Item', 'DataItem', CAT_ITEMS, HINT_TIMEITEM);
{$ENDIF}
end;


end.
